//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "PsiPredProt.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <stdexcept>
#include <iostream>
#include <fstream>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#define LENGTHTEXT 1000
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PsiPredProt::PsiPredProt() {
  
  this->pathPsiPredBIN    = new String ();

  this->sequence          = new String ();
  this->secondStructPred  = new String ();
  this->confidencePred    = new String ();
    
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PsiPredProt::PsiPredProt(const PsiPredProt& psiPredProt) {
  
  this->pathPsiPredBIN    = new String (psiPredProt.pathPsiPredBIN);

  this->sequence          = new String (psiPredProt.sequence);
  this->secondStructPred  = new String (psiPredProt.secondStructPred);
  this->confidencePred    = new String (psiPredProt.confidencePred);
    
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PsiPredProt::PsiPredProt(const PsiPredProt* psiPredProt) {
  
  this->pathPsiPredBIN    = new String (psiPredProt->pathPsiPredBIN);

  this->sequence          = new String (psiPredProt->sequence);
  this->secondStructPred  = new String (psiPredProt->secondStructPred);
  this->confidencePred    = new String (psiPredProt->confidencePred);
    
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PsiPredProt::~PsiPredProt() {
  
  if (this->pathPsiPredBIN)   delete this->pathPsiPredBIN;

  if (this->sequence)         delete this->sequence;
  if (this->secondStructPred) delete this->secondStructPred;
  if (this->confidencePred)   delete this->confidencePred;
    
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PsiPredProt::PathPsiPredBIN (String* pathPsiPredBIN) {
  
  if (pathPsiPredBIN) this->pathPsiPredBIN->In(pathPsiPredBIN);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PsiPredProt::Sequence (String* sequence) {
  
  if (sequence) this->sequence->In(sequence);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PsiPredProt::SecondStructPred (String* secondStructPred) {
  
  if (secondStructPred) this->secondStructPred->In(secondStructPred);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PsiPredProt::ConfidencePred (String* confidencePred) {
  
  if (confidencePred) this->confidencePred->In(confidencePred);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* PsiPredProt::PathPsiPredBIN (void) {
   
  return this->pathPsiPredBIN;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* PsiPredProt::Sequence (void) {
  
  return this->sequence;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* PsiPredProt::SecondStructPred (void) {
  
  return this->secondStructPred;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* PsiPredProt::ConfidencePred (void) {
  
  return this->confidencePred;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PsiPredProt::PredictSecondaryStructure (void) {
  
  if (!this->sequence       || !this->sequence->Length() ||
      !this->pathPsiPredBIN || !this->pathPsiPredBIN->Length()) 
    return false;

  this->sequence->RTrim();
  
  fstream file;
  
  file.open("psiPredProtein.fasta", fstream::out);
  if (!file.is_open()) return false;
  file << ">PAP0001" << endl << this->sequence->Out() << endl;
  file.close();
  
  char command [LENGTHTEXT + 1];
  sprintf(command, "%s psiPredProtein.fasta\0", this->pathPsiPredBIN->Out());
  printf("%s psiPredProtein.fasta\n", this->pathPsiPredBIN->Out());
  int status = system(command);
  
  String namefileResult ("psiPredProtein.horiz");  
  
  bool result = this->ReadPsiPredResult(&namefileResult);
  
  sprintf(command, "rm psiPredProtein.*\0");
  status = system(command);
  
  return result;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PsiPredProt::ReadPsiPredResult(String* namefile) {
  
  if (!namefile || !namefile->Length()) return false;
  
  fstream file;
  char    buffer [LENGTHTEXT + 1];
  
  file.open(namefile->Out(), fstream::in);
  if (!file.is_open()) return false;
  
  String seq;
  
  this->confidencePred->In("");
  this->secondStructPred->In("");
  
  while (!file.eof()) {
    
    file.getline(buffer, LENGTHTEXT);
    
    if (strstr(buffer, "Conf:"))  {
      this->confidencePred->Add(buffer + 6);
      this->confidencePred->RTrim();
    }
    if (strstr(buffer, "Pred:")) {
      this->secondStructPred->Add(buffer + 6);
      this->secondStructPred->RTrim();
    }
    if (strstr(buffer, "AA:")) {
      seq.Add(buffer + 6);
      seq.RTrim();
    }
    
  }
  
  if (strcmp(this->sequence->Out(), seq.Out()) != 0) {
    
    this->confidencePred->In("");
    this->secondStructPred->In("");
    
    return false;
      
  }
  
  file.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
